package com.codefalse.mybatis.generator.controller;

import com.codefalse.mybatis.generator.freemarker.ExtMapperModel;
import com.codefalse.mybatis.generator.model.ConfigModel;
import com.codefalse.mybatis.generator.model.GenerateConfigModel;
import com.codefalse.mybatis.generator.model.TableModel;
import com.codefalse.mybatis.generator.util.GenerateUtils;
import com.codefalse.mybatis.generator.view.GenerateDialogView;
import de.felixroske.jfxsupport.FXMLController;
import freemarker.template.Template;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.stage.WindowEvent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.CaseUtils;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.*;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.mybatis.generator.internal.NullProgressCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author songxiangfeng
 * Created At 2019-12-19 19:30
 */
@FXMLController
@Slf4j
public class GenerateDialogController extends NullProgressCallback implements EventHandler<WindowEvent> {
    private static List<String> warnings = new ArrayList<>();

    @FXML
    private Label totalLabel;
    @FXML
    private Label generateTablesLabel;
    @FXML
    private TextArea remarkArea;
    @FXML
    private ListView logListView;
    @FXML
    private TabPane confirmTabPane;

    @Autowired
    private GenerateDialogView dialogView;
    @Autowired
    private Map<String, GenerateConfigModel> configModelMap;
    @Autowired
    private ConfigModel configModel;

    private freemarker.template.Configuration configuration = null;

    @Override
    public void introspectionStarted(int totalTasks) {
        logListView.getItems().add("准备开始生成代码");
    }

    @Override
    public void startTask(String taskName) {
        logListView.getItems().add(taskName);
    }

    @Override
    public void done() {
        //开始检查扩展Dao生成
        GenerateConfigModel generateConfigModel = configModelMap.get(configModel.getDatabase());
        List<TableModel> tableModels = generateConfigModel.getTableModelList();
        if (tableModels != null && !tableModels.isEmpty()) {
            //路径
            String packagePath = generateConfigModel.getExtMapperPackage().replaceAll("\\.", "\\\\");
            String resourcePath = generateConfigModel.getExtXmlPackage().replaceAll("\\.", "\\\\");

            String javaPath = generateConfigModel.getProjectPath() + generateConfigModel.getJavaPath() + "\\" + packagePath;
            String resPath = generateConfigModel.getProjectPath() + generateConfigModel.getJavaPath() + "\\" + resourcePath;
            File javaFile = new File(javaPath);
            if (!javaFile.exists()) {
                javaFile.mkdirs();
            }
            File resFile = new File(resPath);
            if (!resFile.exists()) {
                resFile.mkdirs();
            }

            Map<String, Object> map = new HashMap<>();
            map.put("modelPackage", generateConfigModel.getModelPackage());
            map.put("mapperPackage", generateConfigModel.getMapperPackage());
            map.put("extMapperPackage", generateConfigModel.getExtMapperPackage());
            try {
                Template extMapperTemplate = configuration.getTemplate("extMapper.ftl");
                Template extXmlTemplate = configuration.getTemplate("extXml.ftl");
                for (TableModel tableModel : tableModels) {
                    String tableName = tableModel.getTable();
                    tableName = CaseUtils.toCamelCase(tableName, true, '_');
                    map.put("tableName", tableName);
                    File extMapperFile = new File(javaPath + "\\" + tableName + "Dao.java");
                    if (extMapperFile.exists()) {
                        logListView.getItems().add("Existing file " + extMapperFile.getPath());
                    } else {
                        logListView.getItems().add("Save file " + extMapperFile.getPath());
                        extMapperTemplate.process(map, new FileWriter(extMapperFile));
                    }

                    File extXmlFile = new File(resPath + "\\" + tableName + "Dao.xml");
                    if (extXmlFile.exists()) {
                        logListView.getItems().add("Existing file " + extXmlFile.getPath());
                    } else {
                        logListView.getItems().add("Save file " + extXmlFile.getPath());
                        extXmlTemplate.process(map, new FileWriter(extXmlFile));
                    }
                }
            } catch (Exception e) {
                logListView.getItems().add("获取ext Template模版失败");
                e.printStackTrace();
            }
        }
        warnings.add("已完成");
        logListView.getItems().addAll(warnings);
        //清空warnings
        warnings.clear();
    }

    public void onGenerateCancelAction() {
        dialogView.closeWindow();
    }

    public void onGenerateSubmitAction() {
        GenerateConfigModel generateConfigModel = configModelMap.get(configModel.getDatabase());
        if (generateConfigModel == null) {
            return;
        }
        //切换为log tab
        confirmTabPane.getSelectionModel().select(1);
        logListView.toBack();

        Configuration config = GenerateUtils.buildConfiguration(configModel, generateConfigModel);
        DefaultShellCallback shellCallback = new DefaultShellCallback(true);
        try {
            MyBatisGenerator generator = new MyBatisGenerator(config, shellCallback, warnings);
            generator.generate(this);
        } catch (Exception e) {
            logListView.getItems().add("发生异常:" + e.getMessage());
        }
    }

    @Override
    public void handle(WindowEvent event) {
        try {
            configuration = new freemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_30);
            configuration.setClassLoaderForTemplateLoading(this.getClass().getClassLoader(), "freemarker");
            configuration.setDefaultEncoding("UTF-8");
        } catch (Exception e) {
            logListView.getItems().add("初始化Ext Template失败");
            e.printStackTrace();
        }

        //初始化
        logListView.getItems().clear();
        confirmTabPane.getSelectionModel().select(0);

        logListView.getItems().add("打开生成代码确认框");
        GenerateConfigModel generateConfigModel = configModelMap.get(configModel.getDatabase());
        if (generateConfigModel == null) {
            logListView.getItems().add("生成失败，信息不完整");
            return;
        }
        String totalTable = "共" + generateConfigModel.getTableModelList().size() + "张表";
        totalLabel.setText(totalTable);
        StringBuilder sb = new StringBuilder();
        for (TableModel model : generateConfigModel.getTableModelList()) {
            sb.append(",").append(model.getTable());
        }
        String tables = sb.toString().substring(1);
        generateTablesLabel.setText(tables);
    }
}
